/**
    思路：开发一个功能程序不要光从页面入手，要从数据入手。（数据逻辑 => 页面逻辑  => 事件处理）
    1. 首先需要对歌词字符串进行处理，解析为想要的对象数组，供后续操作使用
    2. 将字符串歌词转为想要的对象数组之后，根据播放时间找到当前播放的歌词是哪一句，找到其在数组中的位置。
    3. 然后将歌词设置到 页面上，然后高亮的歌词需要在 container 的正中间，需要计算出 ul 的 偏移量
    4. 设置事件，实现效果
 
 */


const doms = {
    audio: document.querySelector('audio'),
    container: document.querySelector('.container'),
    ul: document.querySelector('.lrc-list'),
}


/**
 * 解析歌词字符串
 * - 得到一个歌词对象数组
 * - 歌词对象结构：{time: 时间, words: 歌词}
 */
function parseLrc() {
    const regex =  /\[(\d+:\d+.\d+)](.*)/
    return lrc.split('\n').map(line => {
        const match = line.match(regex) // 匹配时间和歌词
        return match ? {
            time: parseTime(match[1]),
            words: match[2].trim()
        } : undefined
    }).filter(Boolean) // 过滤掉空行
}

/**
 * 解析时间字符串
 * @param {String} time 
 * @returns {Number} 秒数
 */
function parseTime(time) {
    // const [minute, second] = time.split(':')
    // return +minute * 60 + +second
    // map(parseFloat) 等价于 map((value, index, array) => parseFloat(value, index, array)) , parseFloat 只会接收第一个参数
    const [minute, second] = time.split(':').map(parseFloat) 
    return minute * 60 + second
}

// 解析后的歌词数组
const lyrics = parseLrc();
console.log(lyrics);
// 创建歌词元素
createLrcElements()


/**
 * 计算出当前歌词播放到了第几秒
 * 然后找到当前播放的歌词在数组中的位置
 * @param {Number} index  索引
 */
function findIndex() {
    // 获取当前播放时间
    const currentTime = doms.audio.currentTime
    // 遍历歌词数组，找到当前播放时间小于数组中某句歌词的时间的前一句歌词，就是当前需要高亮的歌词
    for(let i = 0; i < lyrics.length; i++) {
        if(currentTime < lyrics[i].time) {
            return i - 1
        }
    }
    // 如果当前播放时间大于所有歌词的时间，则返回最后一句歌词的索引（说明已经播放到最后一句歌词）
    return lyrics.length - 1
}



/**
 * 创建歌词元素 li
 */
function createLrcElements() {
    // 若是不断进行DOM操作，需要做性能优化，可使用文档碎片
    // 添加DOM元素时，几十几百个元素添加，性能损耗很小
    let fragment = document.createDocumentFragment()
    lyrics.forEach(item => {
        const li = document.createElement('li')
        li.textContent = item.words
        li.setAttribute('data-text', item.words)
        // doms.ul.appendChild(li)
        fragment.appendChild(li)
    })
    doms.ul.appendChild(fragment)
}

// 高亮的歌词是需要在 container 的正中间，所以需要计算出 ul 在 container 中的偏移量
// 将读取高度的操作放在函数外面，减少 reflow （每次读取操作获取几何信息的时候都会触发 reflow）
// container 的高度
const containerHeight = doms.container.clientHeight;
// 当前 li 的高度
const currentLiHeight = doms.ul.children[0].clientHeight;
// 最大偏移量
// const maxOffset = doms.ul.clientHeight - containerHeight
const html = document.querySelector('html')
const styleVar = getComputedStyle(html)
const regexTimer = /(\d+)(.*)/


/**
 * 计算 ul 的偏移量 (这个函数是需要反复调用的，内部最好不要直接读取DOM几何信息)
 */
function computedOffset() {
    // 获取高亮歌词的索引
    const index = findIndex()
    // 偏移量 = 当前li的高度（当前li之前的li的高度之和） + 自身的高度 / 2 - container 的高度 / 2
    let offset = currentLiHeight * index + currentLiHeight / 2 - containerHeight / 2
    if (offset < 0) {
        offset = 0
    }
    // 最后一句歌词贴底效果
    // if (offset > maxOffset) {
    //     offset = maxOffset
    // }

    // 设置 ul 的偏移量
    doms.ul.style.transform = `translateY(-${offset}px)`
    // 设置前需要清除掉 active 类
    let li = document.querySelector('.active')
    li && li.classList.remove('active')
    // 设置元素高亮
    li = doms.ul.children[index];
    li && li.classList.add('active')

    // 耗费性能，且卡顿明显
    // const currentTime = doms.audio.currentTime
    // const duration = lyrics[index + 1].time - lyrics[index].time
    // const progress = (currentTime - lyrics[index].time) / duration * 100
    // doms.container.style.setProperty('--progress', `${progress}%`)

    // 没找到高亮歌词索引返回 -1
    if (index > -1) {
        const duration =  index == 0 ? lyrics[index].time : lyrics[index + 1].time - lyrics[index].time
        const timer = styleVar.getPropertyValue('--timer')
        const second = timer.match(regexTimer)[1]
        if (second !== duration) {
            html.style.setProperty('--timer', `${duration}s`)
        }
    }

}

doms.audio.addEventListener('timeupdate', computedOffset)
